package org.sja.log2traffic.dataStructures.timeAgregator;

import org.joda.time.Interval;
import org.joda.time.Period;
import org.joda.time.PeriodType;
import org.sja.log2traffic.ITimeAgregatorCalculator;
import org.sja.log2traffic.dataStructures.ChartPeriodEnum;
import org.sja.log2traffic.dataStructures.ConfigurationEntity;
import org.sja.log2traffic.dataStructures.ICategoryTracker;
import org.sja.log2traffic.dataStructures.ILogData;
import org.sja.log2traffic.dataStructures.INewLogInfo;
import org.sja.log2traffic.dataStructures.IOutputerSupport;
import org.sja.log2traffic.dataStructures.ResultColumn;
import org.sja.log2traffic.dataStructures.ResultTable;


public class LogDataTimeAgregator implements ILogData, IOutputerSupport {
	private LogDataTimeAgregatorElement[][] rawData;
	private ITimeAgregatorCalculator logDataHelper;
	private ConfigurationEntity configurationFromTo;
	
	public static final ResultColumn RESULT_COL_1 = new ResultColumn("Count");
	public static final ResultColumn RESULT_COL_2 = new ResultColumn("maxRespTime");
	public static final ResultColumn RESULT_COL_3 = new ResultColumn("avgRespTime");

	public LogDataTimeAgregator(ConfigurationEntity configurationFromTo, ITimeAgregatorCalculator logDataHelper) {
		this(configurationFromTo, logDataHelper, null);
	}	
	
	public LogDataTimeAgregator(ConfigurationEntity configurationFromTo, ITimeAgregatorCalculator logDataHelper, ICategoryTracker categoryTracker) {
		this.logDataHelper = logDataHelper;
		this.configurationFromTo = configurationFromTo;
		Interval interval = new Interval(getFrom(), getTo());
		Period periodDays = interval.toPeriod(PeriodType.days());
		Period periodHours = interval.toPeriod(PeriodType.hours());

		int howManyElements = -1;
		
		if (configurationFromTo.getChartPeriodEnum() == ChartPeriodEnum.DAY){
			howManyElements = periodDays.getDays();
		} else if (configurationFromTo.getChartPeriodEnum() == ChartPeriodEnum.HOUR){
			howManyElements = periodHours.getHours();
		}
		
		this.rawData = new LogDataTimeAgregatorElement[howManyElements][(int) getAmountOfMinors()];
		for (int i = 0; i < this.rawData.length; ++i) {
			for (int j = 0; j < this.rawData[i].length; ++j) {
				this.rawData[i][j] = new LogDataTimeAgregatorElement(i, j, categoryTracker);
			}
		}
	}

	@Override
	public INewLogInfo getLogInfo(Long time) {
		return logDataHelper.getLogInfo(this, time);
	}

	public long getFrom() {
		return configurationFromTo.getFrom();
	}

	public long getTo() {
		return configurationFromTo.getTo();
	}

	public int getAmountOfMajors() {
		return rawData.length;
	}
	
	public ChartPeriodEnum getChartPeriodEnum() {
		return configurationFromTo.getChartPeriodEnum();
	}
	

	public int getAmountOfMinors() {
		return getHours() * 60;
	}

	public int getHours() {
		if (configurationFromTo.getChartPeriodEnum() == ChartPeriodEnum.DAY){
			//in case of leap year 25 not 24
			return 25;
		} else if (configurationFromTo.getChartPeriodEnum() == ChartPeriodEnum.HOUR) {
			return 1;
		}
		throw new RuntimeException("Something wrong with chart period");
	}

	public LogDataTimeAgregatorElement getRawData(int major, int minor) {
		return rawData[major][minor];
	}

	@Override
	public ResultTable getTable(ConfigurationEntity configurationFromTo, String category) {
		return logDataHelper.calculateTableForAgregate(configurationFromTo, this, category);
	}
	
	public ResultColumn[] getColumnDesciptors(ChartPeriodEnum chartPeriodEnum){
		if (chartPeriodEnum == ChartPeriodEnum.HOUR){
			return new ResultColumn[]{new ResultColumn("date"), new ResultColumn("max. amount of requests per 1 minute"), new ResultColumn("amount of requests within 1 hour"), new ResultColumn("max. resp. time"),new ResultColumn("avg. resp time")};	
		} else if (chartPeriodEnum == ChartPeriodEnum.DAY){
			return new ResultColumn[]{new ResultColumn("date"), new ResultColumn("max. amount of requests per 1 minute"), new ResultColumn("amount of requests within 24 hours"), new ResultColumn("max. resp. time"),new ResultColumn("avg. resp time")};
		} else {
			return new ResultColumn[]{new ResultColumn("date"), new ResultColumn("max. amount of requests per 1 minute"), new ResultColumn("amount of requests WITHIN period of time"), new ResultColumn("max. resp. time"),new ResultColumn("avg. resp time")};
		}
		
	}
}
